home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 12 / Cream of the Crop 12 (Part II) / Cream of the Crop 12 (Part II).iso / OS2 / BLT2_205.ZIP / src / blt2cx05.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-18  |  16.4 KB  |  581 lines

  1. /* 
  2.  *
  3.  * blt2cx05.c - 17-Oct-1995 Cornel Huth 
  4.  * This module is called by blt2demo.c
  5.  * MULTI-TABLE VIEW
  6.  *
  7.  */
  8.  
  9. #include "platform.h"
  10.  
  11. #ifdef ON_OS2
  12.    #include <os2.h>
  13. #endif
  14. #ifdef ON_W95
  15.    #define WIN32_LEAN_AND_MEAN
  16.    #include <windows.h>
  17. #endif
  18.  
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <time.h>
  22. #include <string.h>
  23.  
  24. #ifdef ON_OS2
  25.    #include "bullet2.h"
  26. #endif
  27. #ifdef ON_W95
  28.    #include "bullet95.h"
  29. #endif
  30. #ifdef ON_DOSX
  31.    #include "bulletx.h"
  32. #endif
  33.  
  34. void BuildEmpFieldList(FIELDDESCTYPE fieldList[]);
  35. void BuildDptFieldList(FIELDDESCTYPE fieldList[]);
  36.  
  37. // structures below are byte-aligned by virtue of being of all char type
  38. typedef struct _EmpRecType {
  39. CHAR tag;               // record tag, init to SPACE, * means deleted
  40. CHAR empID[9];          // SSN (not 0T string)
  41. CHAR empLN[16];         // last name
  42. CHAR empFN[16];         // first name
  43. CHAR empHire[8];        // "YYYYMMDD" (not 0T string)
  44. CHAR empDept[6];        // department assigned
  45. } EmpRecType; // 56 bytes
  46.  
  47. typedef struct _DptRecType {
  48. CHAR tag;               // record tag, init to SPACE, * means deleted
  49. CHAR dptID[6];          // department (same format as empDept)
  50. CHAR dptName[16];       // department name
  51. CHAR dptMgrID[9];       // manager of (same format as empID)
  52. CHAR dptNumber[4];      // number of employees assigned to department
  53. } DptRecType; // 36 bytes
  54.  
  55. // Sample data records for the database EMP-DEPT
  56. // C++ probably doesn't like these exact-fit, non-zero-terminating strings
  57.  
  58. EmpRecType empSampleRecords[] = {
  59. //   123456789   1234567890123456   1234567890123456   12345678   123456
  60. ' ',"465309999","Que",             "Barbie",          "19900131","BOSS",
  61. ' ',"445038888","Stewart",         "Jackie",          "19910228","ACC",
  62. ' ',"760443232","Whitman",         "Kelly",           "19920414","HUM",
  63. ' ',"845309944","Beatty",          "Leslie",          "19940122","PRG",
  64. ' ',"555033388","Jasper",          "Amy",             "19930230","PRG",
  65. ' ',"430443222","Hauntos",         "Poco",            "19920414","PRG",
  66. ' ',"365502949","Hopkins",         "Lisa",            "19910121","PRG",
  67. ' ',"685733868","Leonard",         "Rosina",          "19850218","PRG",
  68. ' ',"500945242","Morton",          "Holly",           "19950406","PHY",
  69. ' ',"335209939","Buckly",          "Lois",            "19930715","GO4",
  70. ' ',"745338218","Parker",          "Angie",           "19940412","MKT",
  71. ' ',"860461892","Sosa",            "Rhoda",           "19940623","R&D",
  72. ' ',"225374865","Jefferson",       "Weezie",          "19941106","R&D",
  73. ' ',"115036578","Chung",           "Connie",          "19941205","PRG",
  74. ' ',"240443355","Baker",           "Rosinda",         "19940304","PRG",
  75. };
  76.  
  77. DptRecType dptSampleRecords[] = {
  78. //   123456   1234567890123456   123456789   1234
  79. ' ',"BOSS",  "40th Floor",      "465309999","   1",
  80. ' ',"GO4",   "Secretarial",     "335209939","   1",
  81. ' ',"PRG",   "Programming",     "845309944","   7",
  82. ' ',"R&D",   "Research & Dev",  "860461892","   2",
  83. ' ',"MKT",   "Marketing",       "745338218","   1",
  84. ' ',"ACC",   "Accounting",      "445038888","   1",
  85. ' ',"PHY",   "Psycho Healers",  "500945242","   1",
  86. ' ',"HUM",   "Human Resources", "760443232","   1",
  87. };
  88.  
  89. extern CHAR *collateTable;
  90.  
  91.  
  92. int cx05() {
  93.  
  94. #pragma pack(1)         // recommended around Bullet-accessed data
  95.  
  96. ACCESSPACK AP[3];
  97. DOSFILEPACK DFP;
  98. CREATEDATAPACK CDP;
  99. CREATEINDEXPACK CIP;
  100. HANDLEPACK HP;
  101. OPENPACK OP;
  102.  
  103. CHAR *indexFilename[] = {
  104. "$CX05SSN.IX3",                 // Employee SSN index
  105. "$CX05LNS.IX3",                 // Employee Last name and SSN last-four index
  106. "$CX05DID.IX3"                  // Department ID index
  107. };
  108.  
  109. ULONG indexID[] ={0,0,0};
  110.  
  111. CHAR *keyExpression[] = {
  112. "SSN",
  113. "SUBSTR(LNAME,1,4)+SUBSTR(SSN,6,4)",
  114. "DEPT_ID"
  115. };
  116.  
  117. CHAR *keyBuffer[3][68];
  118.  
  119. CHAR *dataFilename[] = {
  120. "$CX05EMP.DBF",
  121. "$CX05DPT.DBF"
  122. };
  123.  
  124. ULONG dataID[] ={0,0};
  125.  
  126. FIELDDESCTYPE empFieldList[5];  // 5 fields used in Employee data record
  127. EmpRecType empRec;
  128.  
  129. FIELDDESCTYPE dptFieldList[4];  // 4 fields used in Department data record
  130. DptRecType dptRec;
  131.  
  132. #pragma pack()
  133.  
  134. LONG rez;               // return value from Bullet
  135. LONG i;                 // counter
  136. CHAR tmpStr[64];        // misc stuff, non-Bullet related
  137.  
  138. LONG empRecs2Add = sizeof(empSampleRecords) / sizeof(empRec);
  139. LONG dptRecs2Add = sizeof(dptSampleRecords) / sizeof(dptRec);
  140.  
  141. // Clap for the Wolfman
  142.  
  143. printf("Employee-Department database using two data files & three index files\n\n");
  144.  
  145. // Assign fieldlist members (after first zeroing)
  146.  
  147. memset(empFieldList,0,sizeof(empFieldList));
  148. BuildEmpFieldList(empFieldList);
  149. memset(dptFieldList,0,sizeof(dptFieldList));
  150. BuildDptFieldList(dptFieldList);
  151.  
  152. // Delete previous files from any previous run (disregard any error return)
  153.  
  154. DFP.func = DELETE_FILE_DOS;
  155. DFP.filenamePtr = dataFilename[0];
  156. rez = BULLET(&DFP);
  157. DFP.filenamePtr = dataFilename[1];
  158. rez = BULLET(&DFP);
  159.  
  160. for (i=0;i<3;i++) {
  161.    DFP.filenamePtr = indexFilename[i];
  162.    rez = BULLET(&DFP);
  163. }
  164.  
  165. // Create the data files
  166.  
  167. CDP.func = CREATE_DATA_XB;
  168. CDP.filenamePtr = dataFilename[0];
  169. CDP.noFields = 5;
  170. CDP.fieldListPtr = empFieldList;
  171. CDP.fileID = 0x03;
  172. rez = BULLET(&CDP);
  173. if (rez) {
  174.    printf("Failed EMP data file create.  Err: %li\n",rez);
  175.    goto Abend;
  176. }
  177.  
  178. CDP.filenamePtr = dataFilename[1];
  179. CDP.noFields = 4;
  180. CDP.fieldListPtr = dptFieldList;
  181. rez = BULLET(&CDP);
  182. if (rez) {
  183.    printf("Failed DPT data file create.  Err: %li\n",rez);
  184.    goto Abend;
  185. }
  186.  
  187. // Open the data files
  188.  
  189. OP.func = OPEN_DATA_XB;
  190. OP.filenamePtr = dataFilename[0];
  191. OP.asMode = READWRITE | DENYNONE;
  192. rez = BULLET(&OP);
  193. if (rez) {
  194.    printf("Failed EMP data file open.  Err: %li\n",rez);
  195.    goto Abend;
  196. }
  197. dataID[0] = OP.handle;
  198.  
  199. OP.filenamePtr = dataFilename[1];
  200. rez = BULLET(&OP);
  201. if (rez) {
  202.    printf("Failed DPT data file open.  Err: %li\n",rez);
  203.    goto Abend;
  204. }
  205. dataID[1] = OP.handle;
  206.  
  207. // Create index files
  208. // First two index EMP data file, third indexes DPT data file
  209.  
  210. CIP.func = CREATE_INDEX_XB;
  211. CIP.filenamePtr = indexFilename[0];
  212. CIP.keyExpPtr = keyExpression[0];
  213. CIP.xbLink = dataID[0];        
  214. CIP.sortFunction = ASCII_SORT;
  215. CIP.codePage = CODEPAGE;
  216. CIP.countryCode = CTRYCODE;
  217. CIP.collatePtr = NULL;
  218. CIP.nodeSize = 512;
  219. rez = BULLET(&CIP);
  220. if (rez) {
  221.    printf("Failed EMP SSN index file create.  Err: %li\n",rez);
  222.    goto Abend;
  223. }
  224.  
  225. CIP.filenamePtr = indexFilename[1];
  226. CIP.keyExpPtr = keyExpression[1];
  227. CIP.xbLink = dataID[0];        
  228. CIP.sortFunction = NLS_SORT;
  229. CIP.codePage = CODEPAGE;
  230. CIP.countryCode = CTRYCODE;
  231. CIP.collatePtr = collateTable;
  232. CIP.nodeSize = 512;
  233. rez = BULLET(&CIP);
  234. if (rez) {
  235.    printf("Failed EMP NAME index file create.  Err: %li\n",rez);
  236.    goto Abend;
  237. }
  238.  
  239. CIP.filenamePtr = indexFilename[2];
  240. CIP.keyExpPtr = keyExpression[2];
  241. CIP.xbLink = dataID[1];        
  242. CIP.sortFunction = ASCII_SORT;
  243. CIP.codePage = CODEPAGE;
  244. CIP.countryCode = CTRYCODE;
  245. CIP.collatePtr = NULL;
  246. CIP.nodeSize = 512;
  247. rez = BULLET(&CIP);
  248. if (rez) {
  249.    printf("Failed DPT index file create.  Err: %li\n",rez);
  250.    goto Abend;
  251. }
  252.  
  253. // Open the index files
  254.  
  255. OP.func = OPEN_INDEX_XB;
  256. OP.filenamePtr = indexFilename[0];
  257. OP.asMode = READWRITE | DENYNONE;
  258. OP.xbLink = dataID[0];
  259. rez = BULLET(&OP);
  260. if (rez) {
  261.    printf("Failed SSN index file open.  Err: %li\n",rez);
  262.    goto Abend;
  263. }
  264. indexID[0] = OP.handle;
  265.  
  266. OP.filenamePtr = indexFilename[1];
  267. OP.xbLink = dataID[0];
  268. rez = BULLET(&OP);
  269. if (rez) {
  270.    printf("Failed EMP NAME index file open.  Err: %li\n",rez);
  271.    goto Abend;
  272. }
  273. indexID[1] = OP.handle;
  274.  
  275. OP.filenamePtr = indexFilename[2];
  276. OP.asMode = READWRITE | DENYNONE;
  277. OP.xbLink = dataID[1];
  278. rez = BULLET(&OP);
  279. if (rez) {
  280.    printf("Failed DPT index file open.  Err: %li\n",rez);
  281.    goto Abend;
  282. }
  283. indexID[2] = OP.handle;
  284.  
  285. // Insert into the database.  This example has separate inserts for the
  286. // employee file and the department file.  These could be done together,
  287. // with just the single call, however, since this is done in a loop, for
  288. // the number of sample records of each (different counts), and since an
  289. // insert into EMP is distinct from an insert into DPT (not dependent on
  290. // each other), it does not matter that they are done separately -- and
  291. // actually, makes more sense to do so, considering that they are distinct.
  292.  
  293. // Insert into the EMP data file (two index, one data)
  294.  
  295. AP[0].func = INSERT_XB;
  296. AP[0].handle = indexID[0];
  297. AP[0].keyPtr = keyBuffer[0];
  298. AP[0].nextPtr = &AP[1];
  299. AP[1].func = INSERT_XB;
  300. AP[1].handle = indexID[1];
  301. AP[1].keyPtr = keyBuffer[1];
  302. AP[1].nextPtr = NULL;
  303.  
  304. for (i=0;i < empRecs2Add;i++) {
  305.    AP[0].recNo = 0;
  306.    AP[0].recPtr = &empSampleRecords[i];
  307.    AP[1].recNo = 0x80000000;
  308.    AP[1].recPtr = &empSampleRecords[i];
  309.    rez = BULLET(&AP[0]);
  310.    if (rez!=0) 
  311.       break;
  312. };
  313. if (rez) {
  314.    if (rez < 0) {
  315.       rez = abs(rez);
  316.       printf("INSERT_XB #%ld failed, data pack# %ld, err: %ld\n",i,rez,AP[rez-1].stat);
  317.    } 
  318.    else {
  319.       printf("INSERT_XB #%ld failed, index pack# %ld, err: %ld\n",i,rez,AP[rez-1].stat);
  320.    }
  321.    goto Abend;
  322. }
  323.       
  324. // Insert into the DPT data file (one index, one data)
  325.  
  326. AP[2].func = INSERT_XB;         // invariants out of loop
  327. AP[2].handle = indexID[2];
  328. AP[2].keyPtr = keyBuffer[2];
  329. AP[2].nextPtr = NULL;
  330.  
  331. for (i=0;i < dptRecs2Add;i++) {
  332.    AP[2].recNo = 0;
  333.    AP[2].recPtr = &dptSampleRecords[i];
  334.    rez = BULLET(&AP[2]);
  335.    if (rez!=0) 
  336.       break;
  337. };
  338. if (rez) {            
  339.    if (rez < 0) {
  340.       printf("INSERT_XB #%ld failed, data pack# %ld, err: %ld\n",i,rez,AP[2].stat);
  341.    } 
  342.    else {
  343.       printf("INSERT_XB #%ld failed, index pack# %ld, err: %ld\n",i,rez,AP[2].stat);
  344.    }
  345.    goto Abend;
  346. }
  347.    
  348. // Shows a view on the two tables, EMP-DPT, so that all employee info is
  349. // shown, along with the department info that that employee is assigned.
  350. // EMP.DEPT_ID (datafile.fieldname) is a foreign key into DPT.DEPT_ID, and
  351. // so EMP.DEPT_ID for each EMP record is joined with the DPT info for that
  352. // department.  First in SSN order, then in LNAME+last-4 order.  After this, 
  353. // a view on DPT-EMP is shown, listing the managers of each department, and 
  354. // their EMP info.
  355.  
  356. AP[0].func = GET_FIRST_XB;      // using AP[0] since it's convenient to do so
  357. AP[0].handle = indexID[0];      
  358. AP[0].recPtr = &empRec;
  359. AP[0].keyPtr = keyBuffer[0];
  360.  
  361. AP[2].func = GET_EQUAL_XB;      // accessing DPT by foreign key (exact) first
  362. AP[2].handle = indexID[2];      
  363. AP[2].recPtr = &dptRec;
  364. AP[2].keyPtr = keyBuffer[2];
  365.  
  366. i=0;
  367. //       123456789 1234567890123456 1234567890123456 12345678 1234567890123456
  368. printf(" EMP.SSN   LNAME            FNAME            HIRED    DEPARTMENT\n");
  369. rez=BULLET(&AP[0]);
  370. while (rez==0) {
  371.    memcpy(keyBuffer[2],empRec.empDept,6);       // foreign key to key buffer
  372.    rez=BULLET(&AP[2]);                          // and get it to dptRec
  373.    if (rez!=0) strcpy(dptRec.dptName,"Error!");
  374.  
  375.    printf(" %9.9s %-16.16s %-16.16s %8.8s %-16.16s\n",
  376.            empRec.empID,
  377.            empRec.empLN,
  378.            empRec.empFN,
  379.            empRec.empHire,
  380.            dptRec.dptName);
  381.  
  382.    if (rez==0) {
  383.       i++;
  384.       AP[0].func = GET_NEXT_XB;
  385.       rez=BULLET(&AP[0]);
  386.    }
  387. }
  388. if (rez==EXB_END_OF_FILE) rez=0; // expected is ERR_END_OF_FILE
  389. if (rez) {
  390.    printf("(SSN) Failed EMP-DPT view #%ld, err: %ld\n",i,rez);
  391.    goto Abend;
  392. }
  393.  
  394. printf("\nThat was in SSN order.  Press <Enter> for LNAME+last-4 order... ");
  395. gets(tmpStr);
  396. printf("\n");
  397.  
  398. // now the same thing, but in LNAME+last-4 order
  399.  
  400. AP[1].func = GET_FIRST_XB;      // using AP[1] since it's convenient to do so
  401. AP[1].handle = indexID[1];      
  402. AP[1].recPtr = &empRec;
  403. AP[1].keyPtr = keyBuffer[1];
  404.  
  405. AP[2].func = GET_EQUAL_XB;      // accessing DPT by foreign key (exact) first
  406. AP[2].handle = indexID[2];      
  407. AP[2].recPtr = &dptRec;
  408. AP[2].keyPtr = keyBuffer[2];
  409.  
  410. i=0;
  411. //       123456789 1234567890123456 1234567890123456 12345678 1234567890123456
  412. printf(" EMP.SSN   LNAME            FNAME            HIRED    DEPARTMENT\n");
  413. rez=BULLET(&AP[1]);
  414. while (rez==0) {
  415.    memcpy(keyBuffer[2],empRec.empDept,6);       // foreign key to key buffer
  416.    rez=BULLET(&AP[2]);                          // and get it to dptRec
  417.    if (rez!=0) strcpy(dptRec.dptName,"Error!");
  418.  
  419.    printf(" %9.9s %-16.16s %-16.16s %8.8s %-16.16s\n",
  420.            empRec.empID,
  421.            empRec.empLN,
  422.            empRec.empFN,
  423.            empRec.empHire,
  424.            dptRec.dptName);
  425.  
  426.    if (rez==0) {
  427.       i++;
  428.       AP[1].func = GET_NEXT_XB;
  429.       rez=BULLET(&AP[1]);
  430.    }
  431. }
  432. if (rez==EXB_END_OF_FILE) rez=0; // expected is ERR_END_OF_FILE
  433. if (rez) {
  434.    printf("(LNAME) Failed EMP-DPT view #%ld, err: %ld\n",i,rez);
  435.    goto Abend;
  436. }
  437.  
  438. // now for something a little different... the managers' info
  439.  
  440. printf("\nThose were EMP-DPT views.  Press <Enter> for DPT-EMP view (DEPT_ID order)...");
  441. gets(tmpStr);
  442. printf("\n");
  443.  
  444. AP[2].func = GET_FIRST_XB;
  445. AP[2].handle = indexID[2];      
  446. AP[2].recPtr = &dptRec;
  447. AP[2].keyPtr = keyBuffer[2];
  448.  
  449. AP[0].func = GET_EQUAL_XB;      // accessing EMP by foreign key (exact) first
  450. AP[0].handle = indexID[0];      // indexID[0] is the SSN (aka MGR_ID)
  451. AP[0].recPtr = &empRec;
  452. AP[0].keyPtr = keyBuffer[0];
  453.  
  454. i=0;
  455. //       1234567890123456 123456- 1234---8 1234567890123456 1234567890123456
  456. printf(" DEPARTMENT       DEPT_ID ASSIGNED MANAGER\n");
  457. rez=BULLET(&AP[2]);
  458. while (rez==0) {
  459.    memcpy(keyBuffer[0],dptRec.dptMgrID,9);      // foreign key to key buffer
  460.    rez=BULLET(&AP[0]);                          // and get it to empRec
  461.    if (rez!=0) strcpy(empRec.empLN,"Error!");
  462.  
  463.    printf(" %-16.16s %7.6s %4.4s     %s %s\n",
  464.            dptRec.dptName,
  465.            dptRec.dptID,
  466.            dptRec.dptNumber,
  467.            empRec.empFN,
  468.            empRec.empLN);
  469.  
  470.    if (rez==0) {
  471.       i++;
  472.       AP[2].func = GET_NEXT_XB;
  473.       rez=BULLET(&AP[2]);
  474.    }
  475. }
  476. if (rez==EXB_END_OF_FILE) rez=0; // expected is ERR_END_OF_FILE
  477. if (rez) {
  478.    printf("(DEPT_ID) Failed DPT-EMP view #%ld, err: %ld\n",i,rez);
  479.    goto Abend;
  480. }
  481.  
  482. // Fatal errors above come straight to here
  483. Abend:
  484.  
  485. // Close files (index files first then data (recommended but not required))
  486.  
  487. HP.func = CLOSE_INDEX_XB;
  488. for (i=2;i >= 0;i--) {
  489.    if (indexID[i]) {
  490.       HP.handle = indexID[i];
  491.       rez = BULLET(&HP);
  492.       if (rez)
  493.          printf("Failed index #%ld file close.  Err: %li\n",i,rez);
  494.    }
  495. }
  496.  
  497. HP.func = CLOSE_DATA_XB;
  498. for (i=1;i >= 0;i--) {
  499.    if (dataID[i]) {
  500.       HP.handle = dataID[i];
  501.       rez = BULLET(&HP);
  502.       if (rez)
  503.          printf("Failed data #%ld file close.  Err: %li\n",i,rez);
  504.    }
  505. }
  506.  
  507. return rez;
  508.  
  509. }
  510.  
  511. // field list assigns moved down here to just get them the heck out of the way!
  512. // -- actually, all these rez=BULLET() sections would be, should be, 
  513. // wrapped up into generic routines (e.g., InitDatabase(xyz), 
  514. // CreateDatabase(abc), GetEqualOrGreater(), and so on -- all the building
  515. // blocks are already done, you just need to put them together the way you
  516. // want them.
  517.  
  518. ///////////////////////////////////////////////
  519. //
  520. // Init field list items for employee data file
  521. //
  522. ///////////////////////////////////////////////
  523.  
  524. void BuildEmpFieldList(FIELDDESCTYPE fieldList[]) {
  525.  
  526. strcpy(fieldList[0].fieldName, "SSN");
  527. fieldList[0].fieldType = 'C';
  528. fieldList[0].fieldLen = 9;
  529. fieldList[0].fieldDC = 0;
  530.  
  531. strcpy(fieldList[1].fieldName, "LNAME");
  532. fieldList[1].fieldType = 'C';
  533. fieldList[1].fieldLen = 16;
  534. fieldList[1].fieldDC = 0;
  535.  
  536. strcpy(fieldList[2].fieldName, "FNAME");
  537. fieldList[2].fieldType = 'C';
  538. fieldList[2].fieldLen = 16;
  539. fieldList[2].fieldDC = 0;
  540.  
  541. strcpy(fieldList[3].fieldName, "HIRED");
  542. fieldList[3].fieldType = 'D';
  543. fieldList[3].fieldLen = 8;
  544. fieldList[3].fieldDC = 0;
  545.  
  546. strcpy(fieldList[4].fieldName, "DEPT_ID");
  547. fieldList[4].fieldType = 'C';
  548. fieldList[4].fieldLen = 6;
  549. fieldList[4].fieldDC = 0;
  550. }
  551.  
  552. /////////////////////////////////////////////////
  553. //
  554. // Init field list items for department data file
  555. //
  556. /////////////////////////////////////////////////
  557.  
  558. void BuildDptFieldList(FIELDDESCTYPE fieldList[]) {
  559.  
  560. strcpy(fieldList[0].fieldName, "DEPT_ID");
  561. fieldList[0].fieldType = 'C';
  562. fieldList[0].fieldLen = 6;
  563. fieldList[0].fieldDC = 0;
  564.  
  565. strcpy(fieldList[1].fieldName, "NAME");
  566. fieldList[1].fieldType = 'C';
  567. fieldList[1].fieldLen = 16;
  568. fieldList[1].fieldDC = 0;
  569.  
  570. strcpy(fieldList[2].fieldName, "MGR_ID");
  571. fieldList[2].fieldType = 'C';
  572. fieldList[2].fieldLen = 9;
  573. fieldList[2].fieldDC = 0;
  574.  
  575. strcpy(fieldList[3].fieldName, "ASSIGNED");
  576. fieldList[3].fieldType = 'N';
  577. fieldList[3].fieldLen = 4;
  578. fieldList[3].fieldDC = 0;
  579. }
  580.  
  581.